<template>
    <div>
        <div ref="lineChart" style="width: 100%; height:945px;"></div>
    </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref, computed } from 'vue';
import * as echarts from 'echarts/core';

import {
    TitleComponent,
    TooltipComponent,
    LegendComponent,
} from 'echarts/components';
import { GraphChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';

import { getKnowledgeGraph } from '@/api/problems/knowledges';

echarts.use([
    TitleComponent,
    TooltipComponent,
    LegendComponent,
    GraphChart,
    CanvasRenderer
]);


const lineChart = ref(null);
let myChart;

const knowledgePointId = ref(0);

// 使用 defineEmits 声明可以触发的自定义事件  
const emit = defineEmits(['knowledge-click-event']);

var graph;

onMounted(async () => {
    try {
        graph = await getKnowledgeGraph();
        graph.nodes.forEach(function (node) {
            if (node.value == "5180")
                node.fixed = true;
        });

        let option = {
            title: {
                text: 'Knowledge Graph',
                subtext: 'Default layout',
                top: 'bottom',
                left: 'right'
            },
            tooltip: {},
            legend: [
                {
                    //selectedMode: 'single',
                    data: graph.categories.map(function (a) {
                        return a.name;
                    })
                }
            ],
            series: [
                {
                    name: 'Knowledge Graph',
                    type: 'graph',
                    layout: 'force',
                    data: graph.nodes,
                    links: graph.links,
                    categories: graph.categories,
                    roam: true,
                    label: {
                        position: 'right'
                    },
                    force: {
                        repulsion: 100
                    }
                }
            ]
        };

        myChart = echarts.init(lineChart.value);
        myChart.setOption(option);
        myChart.on('click', function (params) {
            emit('knowledge-click-event', params.data);
            console.log(params);
        });
    } catch (e) {
        console.log('error: ', e);
    }
})

onUnmounted(() => {
    if (myChart) {
        console.log('dispose echarts instance.');
        myChart.dispose();
    }
})

const focusByNameEvent = (name) => {
    focusOnNode(name);
}

const addNodeEvent = (knowledge, parentPointId) => {
    let node = {};
    node.id = knowledge.pointId;
    node.category = knowledge.pointLevel;
    node.name = knowledge.pointName;
    node.x = 0.0;
    node.y = 0.0;
    node.symbolSize = 50;
    node.value = knowledge.pointId;
    node.pointId = knowledge.pointId;
    node.pointName = knowledge.pointName;

    let nodes = graph.nodes;
    nodes.push(node);
    let link = {};
    link.source = knowledge.pointId + "";
    link.target = parentPointId + "";
    let links = graph.links;
    links.push(link);

    myChart.setOption({
        series: [
            {
                roam: true,
                data: nodes,
                edges: links
            }
        ]
    });
}

const moveNodeEvent = (knowledge, parentPointId) => {
    let nodeIndex = getNodeIndexById(parentPointId);
    
    let links = graph.links;
    let nodes = graph.nodes;

    let linkIndex = getLinkIndexById(knowledge.pointId);
    let link = links[linkIndex];
    link.target = parentPointId + "";
  
    myChart.setOption({
        series: [
            {
                roam: true,
                data: nodes,
                edges: links
            }
        ]
    });
}

const deleteNodeEvent = (knowledge) => {
    let linkIndex = getLinkIndexById(knowledge.pointId);
    let index = getNodeIndexByName(knowledge.pointName);

    let nodes = graph.nodes;
    let links = graph.links;
    nodes.splice(index, 1);
    links.splice(linkIndex, 1);

    myChart.setOption({
        series: [
            {
                roam: true,
                data: nodes,
                edges: links
            }
        ]
    });
}

function focusOnNode(nodeName) {
    myChart.dispatchAction({
        type: 'highlight', // 或者使用 'focus'，如果 ECharts 支持的话
        seriesIndex: 0, // 图表中关系图（graph）的 seriesIndex
        //dataIndex: index// 你需要实现一个函数来根据节点名称获取其 dataIndex
        name: nodeName
    });
    // 注意：这里没有直接的方法将节点移动到中心，但你可以尝试调整图表的 center 配置或使用滚动 API（如果 ECharts 提供的话）
}

// 假设你有一个函数可以根据节点名称获取其 dataIndex
function getNodeIndexByName(nodeName) {
    // 在这里实现你的逻辑来找到节点在数据中的索引
    let index = 0;
    let matchedIndex = 0;
    myChart.getOption().series[0].data.forEach((e) => {
        if (e.name == nodeName) {
            matchedIndex = index;
        }
        index++;
    })
    return matchedIndex; // 返回节点的 dataIndex
}

// 假设你有一个函数可以根据节点名称获取其 dataIndex
function getLinkIndexById(sourceId) {
    // 在这里实现你的逻辑来找到节点在数据中的索引
    let index = 0;
    let matchedIndex = 0;
    myChart.getOption().series[0].links.forEach((e) => {
        if (e.source == sourceId) {
            matchedIndex = index;
        }
        index++;
    })
    return matchedIndex; // 返回节点的 dataIndex
}

function getNodeIndexById(pointId) {
    // 在这里实现你的逻辑来找到节点在数据中的索引
    let index = 0;
    let matchedIndex = 0;
    myChart.getOption().series[0].data.forEach((e) => {
        if (e.pointId == pointId) {
            matchedIndex = index;
        }
        index++;
    })
    return matchedIndex; // 返回节点的 dataIndex
}

// 使用 defineExpose 来暴露 count的值 和 childEvent方法
defineExpose({
    knowledgePointId,
    focusByNameEvent,
    addNodeEvent,
    moveNodeEvent,
    deleteNodeEvent
});

</script>